/**
 * Copyright 2007-2008. Chongqing First Information & Network Co., Ltd. All
 * rights reserved. <a>http://www.cqfirst.com.cn</a>
 */
package com.cqcis.uip.base.framework.base.impl;

import com.cqcis.uip.base.framework.UIPServiceException;
import com.cqcis.uip.base.framework.UIPTaskException;
import com.cqcis.uip.base.framework.base.AbstractAcceptorSupport;
import com.cqcis.uip.base.framework.common.Role;
import com.cqcis.uip.base.framework.common.Task;
import com.cqcis.uip.base.framework.core.RegisteredServiceContext;
import com.cqcis.uip.base.framework.core.ServiceRole;
import com.cqcis.uip.base.framework.core.ServiceRoleIgnore;
import com.cqcis.uip.base.framework.core.impl.AcceptorServiceAdaptor;
import com.cqcis.uip.base.framework.handlers.CommonService;
import com.cqcis.uip.base.framework.handlers.impl.DefaultServerHandler;

/**
 * @author huangmy
 * @date   2007-12-18
 */
@ServiceRoleIgnore
public class DefaultAcceptor extends AbstractAcceptorSupport {
	private static final long serialVersionUID = 1L;
	private AcceptorServiceAdaptor serviceAdaptor;
    private DefaultCommoner commoner;
    
    @Override
    public void start(RegisteredServiceContext serviceContext) throws Exception {
    	init(); // init first
    	
    	super.start(serviceContext);
    	
    	if (serviceAdaptor.getService() instanceof CommonService) {
    		CommonService service = (CommonService)serviceAdaptor.getService();
    		this.commoner = new DefaultCommoner();
    		this.commoner.setBundleContext(this.bundleContext);
    		this.commoner.registerLogConfiguration(this.getLogConfiguration());
    		this.commoner.setCommonService(service);
    		this.commoner.setEndpointExpression(this.endpointExpression);
    		this.commoner.setInterfaceId(this.interfaceId);
    		this.commoner.setInterfaceName(this.interfaceName);
    		this.commoner.setIntervalTime(this.intervalTime);
    		this.commoner.setLogDir(this.logDir);
    		this.commoner.setLogLevel(this.logLevel);
    		this.commoner.setStreamLogOutputService(this.streamLogOutputService);
    		this.commoner.setThreadNumberExtendTaskResultProcessor(this.threadNumberExtendTaskResultProcessor);
    		this.commoner.setThreadNumberSchedule(this.threadNumberTaskDispatcher);
    		this.commoner.setThreadNumberTaskDispatcher(this.threadNumberTaskDispatcher);
    		this.commoner.setToEndpointExpression(this.toEndpoint.getExpression());
    		this.commoner.setThreadNumberTaskResultDispatcher(this.threadNumberTaskResultDispatcher);
    		this.commoner.setWaitTaskMax(this.waitTaskMax);
    		
    		this.commoner.start(serviceContext);
    	}
    }
    
    @Override
    public void stop(RegisteredServiceContext serviceContext) throws Exception {
    	if (this.commoner != null) {
    		this.commoner.stop(serviceContext);
    	}
    	super.stop(serviceContext);
    }
    
    private void init() {
    	if (serviceAdaptor.getBeforeService() == null) {
    		throw new NullPointerException("the before service must be set for getting a log id.");
    	}
    	
    	DefaultServerHandler handler = new DefaultServerHandler();    	
    	handler.setBeforeService(serviceAdaptor.getBeforeService());//预处理
    	handler.setService(serviceAdaptor.getService());// 业务层处理
    	
    	setHandler(handler);
    	
    	setDecoder(serviceAdaptor.getObjectDecoder()); //读数据解码器 
    	setEncoder(serviceAdaptor.getObjectEncoder()); //写数据编码器
    	
    	if (serviceAdaptor.getReadFilters() != null) {
    		setReadFilters(serviceAdaptor.getReadFilters());
    	}
    	
    	if (serviceAdaptor.getWriteFilters() != null) {
    		setWriteFilters(serviceAdaptor.getWriteFilters());
    	}
    	
    	setStreamRecord(serviceAdaptor.isDefaultStreamRecord());
    }
    
    @Override
    protected boolean doSchedule() {
    	return doScheduleSync(getTaskQueue().poll());
    }
    
    @Override
    protected boolean doScheduleSync(Task task) {
    	if (this.commoner == null) {
			throw new UIPServiceException("the service maybe not implements CommonService.");
		}
    	try {
			return this.commoner.scheduleSync(task);
		} catch (Exception e) {
			throw new UIPTaskException(e);
		}
    }
	
	@Override
	protected void doStart() throws Exception {
		// do nothing		
	}

	@Override
	protected void doStop() throws Exception {
		// do nothing		
	}
    
	@ServiceRole(Role.SOCKET_SERVER)
	public void setServiceAdaptor(AcceptorServiceAdaptor serviceAdaptor) {
		this.serviceAdaptor = serviceAdaptor;
	}
}
